package com.sino.operation.service.business;

import cn.hutool.json.JSONUtil;
import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.sino.operation.commons.ConstantValue;
import com.sino.operation.commons.commonEnum.TaskStateEnum;
import com.sino.operation.config.persistence.MyPersistence;
import com.sino.operation.entity.BizOperateLog;
import com.sino.operation.entity.BizTranslist;
import com.sino.operation.entity.SysAbMessage;
import com.sino.operation.mapper.BizTranslistMapper;
import com.sino.operation.mapper.SerchMapper;
import com.sino.operation.param.out.EscReciveByCounter;
import com.sino.operation.param.out.EscReceiveByCounterToAccount;
import com.sino.operation.service.BizTranslistService;
import com.sino.operation.service.business.inter.StartService;
import com.sino.operation.util.PersistenceUtil;
import com.sino.operation.util.ReflectExecuteUtil;
import com.sino.operation.util.StringUtil;
import com.sino.operation.util.TimeUtil;
import com.sino.operation.vo.PublicInfo;
import com.sino.operation.vo.StartFlowParam;
import lombok.Synchronized;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.client.RestTemplate;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * TOD
 *
 * @author Administrator
 * date 2021/10/16 0016 13:51
 */
@Service
public class StartServiceImpl implements StartService{

    @Autowired
    private BizTranslistService bizTranslistService;

    @Autowired
    MyPersistence myPersistence;

    @Autowired(required = false)
    private SerchMapper serchMapper;

    @Autowired(required = false)
    private BizTranslistMapper bizTranslistMapper;

    @Override
    public String startTrans(EscReciveByCounter escReciveByCounter) throws Exception {
        PublicInfo publicInfo = escReciveByCounter.getEscBody().getPublicInfo();
        String tranCode = publicInfo.getTranCode();
        BizTranslist bizTranslist = new BizTranslist();
        BizOperateLog bizOperateLog = new BizOperateLog();
        SysAbMessage sysAbMessage = new SysAbMessage();
        String message = JSON.toJSONString(escReciveByCounter);
        HashMap<String, Object> varMap = new HashMap<>(16);
        setValue(publicInfo,bizTranslist,sysAbMessage,bizOperateLog,message,varMap);
        PersistenceUtil reception = ReflectExecuteUtil.execute("Exec_"+tranCode, "executeReception", varMap, bizTranslist, sysAbMessage,null,null, escReciveByCounter);

        //调用工作流生成一个实例id和processId
        StartFlowParam startFlowParam = new StartFlowParam();
        startFlowParam.setFlowName(ConstantValue.EXCHANGE);
        startFlowParam.setMaps(varMap);
        RestTemplate restTemplate = new RestTemplate();

        reception.addEntity(bizTranslist);
        reception.addEntity(sysAbMessage);
        reception.addEntity(bizOperateLog);
        List<Object> paramObject = reception.getParamObject();
        myPersistence.save(paramObject);
        String processesId = restTemplate.postForObject(ConstantValue.FLOWMANAGER+ConstantValue.DEPLOY_START, startFlowParam, String.class);
        sysAbMessage.setFlowId(processesId);
        bizTranslist.setFlowId(processesId);
        List<Object> Entity = reception.getParamObject();
        myPersistence.save(Entity);
        return bizTranslist.getJournalNo();
    }

    @Override
    public String startTrans(EscReceiveByCounterToAccount escReceiveByCounterToAccount) throws Exception {
        HashMap<String, Object> varMap = new HashMap<>(16);
        PublicInfo publicInfo = escReceiveByCounterToAccount.getEscBodyByAccount().getPublicInfo();
        BizTranslist bizTranslist = new BizTranslist();
        BizOperateLog bizOperateLog = new BizOperateLog();
        SysAbMessage sysAbMessage = new SysAbMessage();
        String jsonStr = JSONUtil.toJsonStr(escReceiveByCounterToAccount);
        String tranCode = publicInfo.getTranCode();
        setValue(publicInfo,bizTranslist,sysAbMessage,bizOperateLog,jsonStr,varMap);
        PersistenceUtil persistenceUtil = ReflectExecuteUtil.execute("Exec_"+tranCode, "executeReception", varMap, bizTranslist, sysAbMessage, bizOperateLog,null, escReceiveByCounterToAccount);

        persistenceUtil.addEntity(bizTranslist);
        persistenceUtil.addEntity(sysAbMessage);
        persistenceUtil.addEntity(bizOperateLog);
        List<Object> paramObject = persistenceUtil.getParamObject();
        myPersistence.save(paramObject);
        StartFlowParam startFlowParam = new StartFlowParam();
        startFlowParam.setFlowName("AccountAll:1:28d9bc37-3b85-11ec-986d-00e099000b29");
        startFlowParam.setMaps(varMap);
        RestTemplate restTemplate = new RestTemplate();
        String processesId = restTemplate.postForObject(ConstantValue.FLOWMANAGER+ConstantValue.DEPLOY_START, startFlowParam, String.class);
        sysAbMessage.setFlowId(processesId);
        bizTranslist.setFlowId(processesId);
        List<Object> Entity = persistenceUtil.getParamObject();
        myPersistence.save(Entity);

        return bizTranslist.getJournalNo();
    }

    @Override
    public void chargeTest(String journalNo) throws Exception {
        QueryWrapper<BizTranslist> wrapper = new QueryWrapper<>();
        wrapper.eq("journal_no",journalNo);
        BizTranslist bizTranslist = bizTranslistMapper.selectOne(wrapper);
        PersistenceUtil persistenceUtil = ReflectExecuteUtil.execute("Exec_710307", "executeCharge", null, bizTranslist, null, null, null, null);
        persistenceUtil.addEntity(bizTranslist);
        List<Object> paramObject = persistenceUtil.getParamObject();
        myPersistence.save(paramObject);
    }

    public @Synchronized String creatJournalNo(String userName){
        String currentTime = TimeUtil.getDateTime();
        String transId = serchMapper.selectTransId();
        return "BPR"+userName+currentTime+transId.format("%05d", Integer.parseInt(transId));
    }

    public void setValue(PublicInfo publicInfo, BizTranslist bizTranslist, SysAbMessage sysAbMessage, BizOperateLog bizOperateLog, String messageAccept, Map varMap){

        //region 取出公共信息里面的值，加入记账表中
        String tellPost = publicInfo.getTellerPost();
        String tellerCode = publicInfo.getTellerCode();
        String tellerName = publicInfo.getTellerName();
        String tranDate = publicInfo.getTranDate();
        String tranTime = publicInfo.getTranTimeStamp();
        String orgCode = publicInfo.getOrgCode();
        String orgName = publicInfo.getOrgName();
        String imageId = publicInfo.getImageId();
        String tranCode = publicInfo.getTranCode();
        String businessType = publicInfo.getBusinessType();
        String journalNo = creatJournalNo(tellerCode);

        //流水表
        bizTranslist.setJournalNo(journalNo);
        bizTranslist.setTransCode(tranCode);
        bizTranslist.setOrgCode(orgCode);
        bizTranslist.setImageId(imageId);
        bizTranslist.setTransDate(tranDate);
        bizTranslist.setTransTime(tranTime);
        bizTranslist.setTransType(businessType);
        bizTranslist.setTransState(TaskStateEnum.FLOW_STATE_RUNNING.getCode());
        bizTranslist.setOrgName(orgName);
        String date = TimeUtil.getStandardTime();
        bizTranslist.setOrgName(orgName);
        sysAbMessage.setJournalNo(journalNo);
        sysAbMessage.setTime(date);
        sysAbMessage.setMessage(messageAccept);
        sysAbMessage.setMessageAccept(messageAccept);

        //日志记录
        bizOperateLog.setId(StringUtil.getId());
        bizOperateLog.setJournalNo(journalNo);
        bizOperateLog.setOperDate(date);
        bizOperateLog.setTellerPost(tellPost);
        bizOperateLog.setTellerNo(tellerName);

        varMap.put("businessKey",journalNo);
        varMap.put("tranCode",tranCode);
        //endregion
    }
}
